<?php

use think\Request;
use think\facade\Db;

use app\common\model\SiteSetting;
use OSS\OssClient;
use OSS\Core\OssException;

use Qiniu\Auth;
use Qiniu\Storage\UploadManager;


/**
 * Here is your custom functions.
 */


/**
 * 响应失败返回400 JSON
 * @params string
 * @return
 */
function returnFail($msg = 'request fail', $data = null)
{
    return json(['code' => 400, 'msg' => $msg, 'data'=>$data, 'total'=>0, 'timestamp'=>time()]);
}

/**
 * 响应成功返回200 JSON
 * @params string
 * @return
 */
function returnSuccess($msg = 'request success', $data = null, $total = 0)
{
    return json(['code' => 200, 'msg' => $msg, 'data'=>$data, 'total'=>$total, 'timestamp'=>time()]);
}

/**
 * 自定义返回 JSON
 * @params string
 * @return
 */
function returnJson($code = 200, $msg = 'request success', $data = null, $total = 0)
{
    return json(['code' => $code, 'msg' => $msg, 'data'=>$data, 'total'=>$total, 'timestamp'=>time()]);
}

/**
 * bootstrap 返回结果集
 * @params string
 * @return
 */
function returnData($data = [], $total = 0)
{
    return json(['rows'=>$data, 'total'=>$total]);
}
/**
 * 返回指定长度随机字符串
 * @params string
 * @return
 */
function get_random_str($len = 6)
{
    $chars = array(
        "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
        "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
        "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
        "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
        "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
        "3", "4", "5", "6", "7", "8", "9"
    );
    $charsLen = count($chars) - 1;
    // 将数组打乱
    shuffle($chars);
    $output = "";
    for ($i = 0; $i < $len; $i++) {
        $output .= $chars[mt_rand(0, $charsLen)];
    }
    return $output;
}

//返回随机颜色
function random_color(){
    mt_srand((double)microtime()*1000000);
    $c = '';
    while(strlen($c)<6){
        $c .= sprintf("%02X", mt_rand(0, 255));
    }
    return $c;
}

/**
 * 上传文件到阿里云
 * @params string
 * @return
 */
function uploadAliOss($file_name, $file_path, $config = [])
{
    try {
        $accessKeyId = $config['access_key'];
        $accessKeySecret = $config['secret_key'];
        $endpoint = $config['endpoint'];
        $bucket = $config['bucket'];

        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        $r = $ossClient->uploadFile($bucket, $file_name, $file_path);
        return $r['info']['url'];
    } catch (Exception $e) {
        return false;
    }
}

/**
 * 上传文件到七牛云
 * @params string
 * @return
 */
function uploadQnStore($file_name, $file_path, $config = [])
{
    try {
        $auth = new Auth($config['access_key'], $config['secret_key']);
        $token = $auth->uploadToken($config['bucket'], null, 3600);

        $uploadMgr = new UploadManager();
        list($ret, $err) = $uploadMgr->putFile($token, $file_name, $file_path);
        if($err !== null){
            return false;
        }else{
            //返回文件整个路径
            return $config['domain'].$ret['key'];
        }
    }catch (Exception $e)
    {
        return false;
    }
}

/**
 * 格式化时间戳
 * @params string
 * @return
 */
function formatTime($timestamp, $type = 1)
{
    if(empty($timestamp) || strlen($timestamp) != 10)
    {
        return "";
    }
    if($type == 1)
    {
        return date('Y-m-d H:i:s', $timestamp);
    }
}

/**
 * 获取毫秒时间戳
 * @params string
 * @return
 */
function getMillisecond() {
    list($s1, $s2) = explode(' ', microtime());
    return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
}

/**
 * 获取文件后缀名
 * @params string
 * @return
 */
function get_extension($file)
{
    $file = preg_split('/\./', $file);
    return end($file);
}

/**
 * 通用上传文件
 * @params $type = file/img 文件或者图片类型
 * @params $is_admin=1 是后台上传的文件如果是图片则会保存在数据库 = 0 不会保存在数据库
 * @return
 */
function uploadFileCommon($request, $is_admin = 0)
{
    $img_rule = ['jpg','jpeg','png','gif','bmp','svg','webp'];
    $file = $request->file('file');
    $file_mine = $file->getOriginalExtension();  //获取文件后缀名
    //上传配置
    $upload_setting = SiteSetting::getUploadSetting();
    //获取设置的本地存储位置
    $local_path = $upload_setting['path_info']['local'];

    if(in_array($file_mine, $img_rule))
    {
        //是图片
        $file_type = 'image';
        //存储在本地服务器的文件地址
        if(empty($local_path['img_path']))
        {
            $local_path['img_path'] = '/upload/image/';
        }
        $return_local_path = $local_path['img_path'].date('Ymd').'/';
    }else{
        //其他文件
        $file_type = 'other';
        //存储在本地服务器的文件地址
        if(empty($local_path['other_path']))
        {
            $local_path['other_path'] = '/upload/file/';
        }
        $return_local_path = $local_path['other_path'].date('Ymd').'/';
    }
    //允许的后缀名
    $file_ext_rule = explode(',', $upload_setting['file_ext']);
    //上传的文件大小
    $max_upload_size = $upload_setting['upload_file_size'];
    $save_local_path = public_path().$return_local_path;
    if($file->isValid())
    {
        if(!empty($file_ext_rule) && !in_array($file_mine, $file_ext_rule))
        {
            return returnFail('上传失败，文件类型不合法');
        }
        $file_size = $file->getSize();  // 文件大小
        if($max_upload_size!= 0 && (ceil($file_size/1024) > $max_upload_size))
        {
            return returnFail('上传文件超过大小限制'.$max_upload_size.'kb以内');
        }
        //重命名文件
        $file_name = md5(get_random_str(6).time()).'.'.$file_mine;

        $save_name = \think\facade\Filesystem::disk('public')->putFileAs( date('Ymd'), $file, $file_name);

        //上传文件三方存储的位置目前支持 阿里云 七牛云
        switch ($upload_setting['upload_path'])
        {
            case 'local':

                $file_path = $local_path['local_domain'].$return_local_path.$file_name;
                break;
            case 'ali':

                $file_path = uploadAliOss($file_name, $save_local_path.$file_name, $upload_setting['path_info'][$upload_setting['upload_path']]);
                if(!$file_path)
                {
                    return returnFail('阿里云上传文件失败');
                }
                break;
            case 'qn':
                $file_path = uploadQnStore($file_name, $save_local_path.$file_name, $upload_setting['path_info'][$upload_setting['upload_path']]);
                if(!$file_path)
                {
                    return returnFail('七牛云上传文件失败');
                }
                break;
            default:
                $file_path = $return_local_path.$file_name;
                break;
        }
        //判断上传到三方存储是否删除本地文件
        if($upload_setting['upload_path'] != 'local')
        {
            if($upload_setting['delete_local'] == 1)
            {
                deleteLocalFile($save_local_path.$file_name);
            }
        }
        //如果是后台管理员账号上传
        if($is_admin == 1)
        {
            if($file_type == 'image')
            {
                //记录
                $img['admin_id']  = $request->admin_info['id'];
                $img['origin_name'] = $file->getOriginalName();
                $img['name']      = $file_name;
                $img['file_path'] = $file_path;
                $img['save_path'] = $upload_setting['upload_path'];
                $img['mine']      = $file_mine;
                $img['size']      = $file_size/1024;  //kb
                $img['create_time'] = time();
                Db::name('upload_img')->insert($img);

                return returnSuccess('上传成功',$img['file_path']);
            }else{
                $res['file_path'] = $file_path;
                $res['file_name'] = $file->getOriginalName();
                $res['size']      = $file_size/1024;  //kb
                $res['time']      = date('Y-m-d H:i:s');

                return returnSuccess('上传成功',$res);
            }
        }else{

            return returnSuccess('上传成功',$file_path);
        }
    }else{
        return returnFail('上传文件无效');
    }
}

/**
 * 删除本地文件
 * @params string
 * @return
 */
function deleteLocalFile($file_path)
{
    if($file_path && file_exists($file_path))
    {
        @unlink($file_path);
    }
}

/**
 * 获取本地文档本地访问域名
 * @params string
 * @return
 */
function getUploadLocalDomain()
{
    $info = \app\common\model\SiteSetting::getUploadSetting();
    if(!empty($info) && !empty($info['path_info']) && !empty($info['path_info']['local']) && !empty($info['path_info']['local']['local_domain']))
    {
        return $info['path_info']['local']['local_domain'];
    }else{
        return request()->host();
    }
}